﻿namespace GreenIsomer.Web.Controls.JQuery {
	using System;
	using System.Collections.Generic;
	using System.Reflection;

	/// <summary>
	/// Allows the association of a CSS class with each member of the GreenIsomer.Web.Controls.JQuery.Symbol enumeration.
	/// </summary>
	[AttributeUsage(AttributeTargets.Field)]
	public sealed class SymbolAttribute : Attribute {


		#region Constants/Static Readonly Fields

		private static readonly object loadLock = new object();
		private static readonly Dictionary<Symbol, string> cssClasses = new Dictionary<Symbol, string>();

		#endregion


		#region Static Methods

		/// <summary>
		/// Returns the CSS class associated with a symbol defined by the GreenIsomer.Web.Controls.JQuery.Symbol enumeration.
		/// </summary>
		/// <param name="symbol">The symbol member to cross-reference for a CSS class.</param>
		/// <returns>The associated CSS class.</returns>
		/// <exception cref="ArgumentException">Value is not defined.</exception>
		public static string GetCssClass(Symbol symbol) {
			if(!Enum.IsDefined(typeof(Symbol), symbol)) throw new ArgumentException("Value is not defined.", "symbol");

			string value;
			if(cssClasses.TryGetValue(symbol, out value)) return value;

			lock(loadLock) {

				if(cssClasses.TryGetValue(symbol, out value)) return value;

				FieldInfo fieldInfo = typeof(Symbol).GetField(symbol.ToString());
				object[] symbolAttributes = fieldInfo.GetCustomAttributes(typeof(SymbolAttribute), false);
				SymbolAttribute symbolAttribute = (SymbolAttribute)symbolAttributes[0];
				string cssClass = symbolAttribute.CssClass;

				cssClasses.Add(symbol, cssClass);
				return cssClass;
			}
		}

		#endregion


		#region Members

		private readonly string cssClass;

		#endregion


		#region Constructors

		/// <summary>
		/// Initializes an instance of the GreenIsomer.Web.Controls.JQuery.SymbolAttribute class.
		/// </summary>
		/// <param name="cssClass">The CSS class to associate with the attached enumeration member.</param>
		public SymbolAttribute(string cssClass) {
			this.cssClass = cssClass;
		}

		#endregion


		#region Properties

		/// <summary>
		/// The CSS class to associate with the attached enumeration member.
		/// </summary>
		public string CssClass {
			get { return cssClass; }
		}

		#endregion


	}

}